#include <iostream>
#include <ostream>

using std::cout;
using std::endl;

//Point类型不需要做任何改变
class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {   cout << "Point(int,int)" << endl;}

    void print() const
    {   
        cout << "(" << _ix 
             << "," << _iy
             << ")" << endl;
    }

private:
    int _ix;
    int _iy;
};

template <class T>
class Singleton
{
    //单例对象希望能够自动释放
    class AutoRelease
    {
    public:
        AutoRelease() { cout << "AutoRelease()" << endl;    }
        ~AutoRelease() { 
            cout << "~AutoRelease()" << endl;    
            if(_pInstance) {
                delete _pInstance;
                _pInstance = nullptr;
            }
        }
    };
public:
    template <class... Args>
    static T * getInstance(Args... args)
    {
        if(nullptr == _pInstance) {
            _pInstance = new T(args...);
            //调用该函数时，让_ar对象出现一次
            //这样编译时，就会推导出一个相应类型的_ar对象来
            //加上void是为了消除警告
            (void)_ar;
        }
        return _pInstance;
    }

private:
    Singleton() {}
    ~Singleton() {}

private:
    static T * _pInstance;
    static AutoRelease _ar;
};

template <class T>
T * Singleton<T>::_pInstance = nullptr;

//typename或者class 放在这里是为了告诉编译器AutoRelease是
//一个嵌套类型, 不是Singleton的数据成员
template <class T>
//typename Singleton<T>::AutoRelease Singleton<T>::_ar;
class Singleton<T>::AutoRelease Singleton<T>::_ar;

int main()
{
    cout << "enter main" << endl;
    Point * pt1 = Singleton<Point>::getInstance(1, 2);
    Point * pt2 = Singleton<Point>::getInstance(10, 20);
    cout << "pt1:" << pt1 << endl;
    cout << "pt2:" << pt2 << endl;
    pt1->print();
    pt2->print();

    return 0;
}

